package com.xnx3.j2ee.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
//import org.elasticsearch.client.Request;
//import org.elasticsearch.client.RequestOptions;
//import org.elasticsearch.client.Response;
//import org.elasticsearch.client.core.CountRequest;
//import org.elasticsearch.client.core.CountResponse;
//import org.elasticsearch.index.query.QueryBuilder;
//import org.elasticsearch.index.query.QueryBuilders;
//import org.elasticsearch.search.builder.SearchSourceBuilder;
//import org.elasticsearch.search.sort.SortBuilder;
//import org.elasticsearch.search.sort.SortBuilders;
//import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;
import com.xnx3.Lang;
import com.xnx3.StringUtil;
//import com.xnx3.elasticsearch.jsonFormat.JsonFormatInterface;
import com.xnx3.j2ee.Global;
import com.xnx3.j2ee.vo.ActionLogListVO;
import com.xnx3.j2ee.vo.ElasticSearchPageListVO;
import net.sf.json.JSONObject;

/**
 * ElasticSearch 工具类。使用此工具类的前提是 application.properties 中配置好了相关参数
 * @author 管雷鸣
 */
//@Component
public class ElasticSearchUtil {
	
//	private static com.xnx3.elasticsearch.ElasticSearchUtil es;
	private static boolean starting = true;						//当前状态是否是在启动中，如果是在启动中（tomcat启动可能需要半分钟），那此处为true，如果tomcat已启动完成加载完了（也就是ElasticSearch 的参数并已经初始化完成），那此处为false
	
//	static {
//		new Thread(new Runnable() {
//			public void run() {
//				
//				//当数据库加载完后，再初始化
//				while(Global.system.size() < 1){
//					try {
//						Thread.sleep(1000);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
//				}
//				
//				//初始化es配置参数
//				String hostname = ApplicationPropertiesUtil.getProperty("wm.elasticsearch.hostname");
//				int port = Lang.stringToInt(ApplicationPropertiesUtil.getProperty("wm.elasticsearch.port"), 9200);
//				String scheme = ApplicationPropertiesUtil.getProperty("wm.elasticsearch.scheme");
//				String username = ApplicationPropertiesUtil.getProperty("wm.elasticsearch.username");
//				String password = ApplicationPropertiesUtil.getProperty("wm.elasticsearch.password");
//				
//				//判断是否使用es进行日志记录，条件便是 hostname 是否为空。若为空，则不使用
//				if(hostname != null && hostname.length() > 0){
//					//使用
//					es = new com.xnx3.elasticsearch.ElasticSearchUtil(hostname, port, scheme);
//					if((username != null && username.length() > 0) && (password != null && password.length() > 0)) {
//						//使用账号密码模式
//						es.setUsernameAndPassword(username, password);
//					}
//					ConsoleUtil.info("开启ElasticSearch进行操作记录");
//					
//					//重写序列化接口
//					es.setJsonFormatInterface(new JsonFormatInterface() {
//						@Override
//						public String mapToJsonString(Map<String, Object> params) {
//							if(params == null){
//								params = new HashMap<String, Object>();
//							}
//							return JSONObject.fromObject(params).toString();
//						}
//					});
//				}
//				
//				starting = false;
//			}
//		}).start();
//	}
	
//	/**
//	 * 获取 {@link com.xnx3.elasticsearch.ElasticSearchUtil} 对象
//	 * @return application.properties 中 wm.elasticsearch 相关参数所配置初始化的{@link com.xnx3.elasticsearch.ElasticSearchUtil}对象。拿到可直接使用。
//	 */
//	public static com.xnx3.elasticsearch.ElasticSearchUtil getElasticSearch(){
//		if(isStarting()) {
//			ConsoleUtil.debug("elasticsearch 尚未初始化，请控制在项目启动成功后再调用此");
//			return null;
//		}
//		if(!isUsed()) {
//			ConsoleUtil.debug("elasticsearch 未使用。若要使用，可配置 application.properties 中 wm.elasticsearch 相关参数");
//			return null;
//		}
//		return es;
//	}
//	
//	/**
//	 * 是否使用 ElasticSearch （application.properties中是否已配置es的参数）
//	 * @return true:使用
//	 */
//	public static boolean isUsed() {
//		if(es == null){
//			return false;
//		}
//		return true;
//	}
//	
//	/**
//	 * 当前状态是否是在启动中，如果是在启动中（tomcat启动可能需要半分钟），那此处为true，如果tomcat已启动完成加载完了（也就是ElasticSearch 的参数并已经初始化完成），那此处为false。
//	 * <p>因为如果是在启动中，那</p>
//	 * @return true:使用
//	 */
//	public static boolean isStarting() {
//		return starting;
//	}
//	
//	/**
//	 * 项目启动时，检查创建索引是否存在，如果没有创建，那么自动创建这个索引。
//	 * <p>注意，使用此创建时，会自动创建一个线程Thread，监测 elasticsearch 的初始化，当初始化后才会进行创建。一个项目中，不建议要超过20个使用此方法进行监测创建的 indexName</p>
//	 * <p>正常创建索引，</p>
//	 * @param indexName 要创建的索引名字，传入如 userlog
//	 */
//	public static void projectStartCheckCreateIndex(String indexName) {
//		new Thread(new Runnable() {
//			public void run() {
//				while(isStarting()) {
//					try {
//						Thread.sleep(300);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
//				}
//				
//				//如果不使用es，直接退出
//				if(!isUsed()) {
//					return;
//				}
//				
//				//判断index是否创建了，如果没创建，进行创建
//				if(!es.existIndex(indexName)) {
//					ConsoleUtil.info("自动创建 ElasticSearch 的 index : "+indexName);
//					try {
//						es.createIndex(indexName);
//					} catch (IOException e) {
//						e.printStackTrace();
//					}
//				}
//				
//			}
//		}).start();
//		
//	}

	
	/**
	 * 将日志查询出来，以列表+分页的数据输出
	 * <p>获取到的数据排序规则：这里是按照数据创建时间（time字段），倒序排列，时间越往后的，显示越靠前。当前，前提是你写入数据的时候得有 time 这个字段</p>
	 * @param indexName 索引名字
	 * @param query 查询条件，传入如： name:guanleiming AND age:123
	 * @param everyPageNumber 每页显示几条，最大100
	 * @param request {@link HttpServletRequest} 分页会使用到这个
	 * @return 如果失败， vo.getResult() == ActionLogListVO.FAILURE
	 */
//	public static ElasticSearchPageListVO list(String indexName, String query,int everyPageNumber, HttpServletRequest request) {
//		return list(indexName, query, everyPageNumber, SortBuilders.fieldSort("time").order(SortOrder.DESC), request);
//	}
	
	/**
	 * 将日志查询出来，以列表+分页的数据输出
	 * @param indexName 索引名字
	 * @param query 查询条件，传入如： name:guanleiming AND age:123
	 * @param everyPageNumber 每页显示几条，最大100
	 * @param sort 排序方式。比如按照time字段进行倒序排序，则传入如: 
	 * 	<pre>
	 * 	SortBuilders.fieldSort("time").order(SortOrder.DESC)
	 * 	</pre>
	 * @param request {@link HttpServletRequest} 分页会使用到这个
	 * @return 如果失败， vo.getResult() == ActionLogListVO.FAILURE
	 */
//	public static ElasticSearchPageListVO list(String indexName, String query,int everyPageNumber, SortBuilder sort, HttpServletRequest request) {
//		ElasticSearchPageListVO vo = new ElasticSearchPageListVO();
//		
//		//统计符合条件的总数量
//		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//		CountRequest countRequest = new CountRequest();
//		//构造查询条件
//		if(query != null && query.length() > 0){
//			//有查询条件，才会进行查询，否则会查出所有
//			QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(query);
//			searchSourceBuilder.query(queryBuilder);
//		}
//		countRequest.indices(indexName).source(searchSourceBuilder);
//		long count = 0;
//		CountResponse countResponse = null;
//		try {
//			countResponse = getElasticSearch().getRestHighLevelClient().count(countRequest, RequestOptions.DEFAULT);
//			count = countResponse.getCount();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		Page page = new Page((int) count, everyPageNumber, request);
//		
//		//limit查询条数
//		int limitNumber = everyPageNumber;
//		//判断当前是否是最后一页
//		if(page.isCurrentLastPage()){
//			//最后一页，那limit条数肯定不满足一页多少条的标准了，肯定是要少的，那就计算出当前一共几条，就显示几条
//			limitNumber = (int) (count - page.getLimitStart() );
//		}
//		
//		long max_result_window = 10000;	//默认就是10000
//		try {
//			Response res = getElasticSearch().getRestClient().performRequest(new Request("GET", "/"+indexName+"/_settings"));
//			String text = StringUtil.inputStreamToString(res.getEntity().getContent(), "UTF-8");
//			JSONObject setJson = JSONObject.fromObject(text);
//			JSONObject indexJson = setJson.getJSONObject(indexName).getJSONObject("settings").getJSONObject("index");
//			if(indexJson.get("max_result_window") != null){
//				//自己单独设置过 max_result_window
//				max_result_window = indexJson.getLong("max_result_window");
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		
//		//判断最大显示条数是否超过可显示的最大条数
//		if((page.getLimitStart() + limitNumber) > max_result_window){
//			vo.setBaseVO(ActionLogListVO.FAILURE, "显示最大条数超过系统预设优化的最大条数"+max_result_window+"条。");
//			ConsoleUtil.log("显示最大条数超过系统预设优化的最大条数"+max_result_window+"条。你可以设置ElasticSearch中，"+indexName+"索引的max_result_window属性来设置更大条数。");
//			return vo;
//		}
//		
//		//获取查询结果的数据 
//		List<Map<String, Object>> list = getElasticSearch().search(indexName, query, page.getLimitStart(), limitNumber, SortBuilders.fieldSort("time").order(SortOrder.DESC));
//		for (int i = 0; i < list.size(); i++) {
//			Map<String, Object> map = list.get(i);
//			
//			//兼容以前的阿里云日志服务的版本
//			Object timeObj = map.get("time");
//			if(timeObj == null){
//				map.put("logtime", 0l);
//			}else{
//				map.put("logtime", timeObj);
//			}
//		}
//		vo.setList(list);
//		vo.setPage(page);
//		
//		return vo;
//	}
//	
}
